/*
 * @Author: lixu lixu@puchigames.com
 * @Date: 2025-09-18 11:45:00
 * @LastEditors: lixu lixu@puchigames.com
 * @LastEditTime: 2025-09-18 11:45:00
 * @FilePath: /go-helper/ixLog/index.go
 * @Description: ixLog包入口文件，提供日志功能的统一接口
 */

package ixLog

import (
	"context"
	"fmt"
	"path/filepath"
	"time"
)

// 包级别的便捷函数，用于快速使用

// Quick 快速创建日志器
func Quick() Logger {
	logger, _ := NewDevelopmentLogger()
	return logger
}

// Production 创建生产环境日志器
func Production(appName, logFile string) Logger {
	logger, _ := NewProductionLogger(appName, logFile)
	return logger
}

// Development 创建开发环境日志器
func Development() Logger {
	logger, _ := NewDevelopmentLogger()
	return logger
}

// Test 创建测试环境日志器
func Test() Logger {
	logger, _ := NewTestLogger()
	return logger
}

// File 创建文件日志器
func File(filePath string, level LogLevel) Logger {
	logger, _ := NewFileLogger(filePath, level)
	return logger
}

// Network 创建网络日志器
func Network(network, address string, level LogLevel) Logger {
	logger, _ := NewNetworkLogger(network, address, level)
	return logger
}

// WithConfig 使用配置创建日志器
func WithConfig(config *Config) Logger {
	logger, _ := NewLogger()
	return logger
}

// 追踪相关便捷函数

// TraceFunc 追踪函数执行（装饰器模式）
func TraceFunc(ctx context.Context, name string) (context.Context, func()) {
	ctx, span := StartTrace(ctx, name)

	return ctx, func() {
		FinishTrace(span)
	}
}

// TraceSpan 追踪代码块
func TraceSpan(ctx context.Context, name string, fn func(context.Context) error) error {
	return TraceFunction(ctx, name, fn)
}

// Measure 测量执行时间
func Measure(ctx context.Context, name string, fn func()) {
	MeasureTime(ctx, name, fn)
}

// 业务日志便捷函数

// LogUserAction 记录用户操作
func LogUserAction(ctx context.Context, userID, action string, details map[string]interface{}) {
	if details == nil {
		details = make(map[string]interface{})
	}
	details["user_id"] = userID
	details["action"] = action

	InfoWithFields(details, fmt.Sprintf("用户操作: %s", action))
}

// LogAPICall 记录API调用
func LogAPICall(ctx context.Context, method, endpoint string, statusCode int, duration time.Duration) {
	LogHTTPRequest(ctx, method, endpoint, statusCode, duration)
}

// LogBusinessEvent 记录业务事件
func LogBusinessEvent(ctx context.Context, event string, data map[string]interface{}) {
	if data == nil {
		data = make(map[string]interface{})
	}
	data["event_type"] = "business"
	data["event_name"] = event

	InfoWithFields(data, fmt.Sprintf("业务事件: %s", event))
}

// LogSecurityEvent 记录安全事件
func LogSecurityEvent(ctx context.Context, event string, severity string, details map[string]interface{}) {
	if details == nil {
		details = make(map[string]interface{})
	}
	details["event_type"] = "security"
	details["event_name"] = event
	details["severity"] = severity

	var level LogLevel
	switch severity {
	case "low":
		level = INFO
	case "medium":
		level = WARN
	case "high":
		level = ERROR
	case "critical":
		level = FATAL
	default:
		level = WARN
	}

	logger := LoggerFromContext(ctx)
	if ixLogger, ok := logger.(*ixLogger); ok {
		ixLogger.log(level, fmt.Sprintf("安全事件: %s", event), details, nil, ctx)
	} else {
		switch level {
		case INFO:
			logger.WithFields(details).Info(fmt.Sprintf("安全事件: %s", event))
		case WARN:
			logger.WithFields(details).Warn(fmt.Sprintf("安全事件: %s", event))
		case ERROR:
			logger.WithFields(details).Error(fmt.Sprintf("安全事件: %s", event))
		case FATAL:
			logger.WithFields(details).Fatal(fmt.Sprintf("安全事件: %s", event))
		}
	}
}

// LogPerformance 记录性能指标
func LogPerformance(ctx context.Context, operation string, duration time.Duration, metrics map[string]interface{}) {
	if metrics == nil {
		metrics = make(map[string]interface{})
	}
	metrics["operation"] = operation
	metrics["duration"] = duration.String()
	metrics["duration_ms"] = duration.Milliseconds()
	metrics["event_type"] = "performance"

	// 根据执行时间确定日志级别
	var level LogLevel
	switch {
	case duration > 5*time.Second:
		level = ERROR
	case duration > 1*time.Second:
		level = WARN
	default:
		level = DEBUG
	}

	logger := LoggerFromContext(ctx)
	if ixLogger, ok := logger.(*ixLogger); ok {
		ixLogger.log(level, fmt.Sprintf("性能指标: %s", operation), metrics, nil, ctx)
	} else {
		switch level {
		case DEBUG:
			logger.WithFields(metrics).Debug(fmt.Sprintf("性能指标: %s", operation))
		case WARN:
			logger.WithFields(metrics).Warn(fmt.Sprintf("性能指标: %s", operation))
		case ERROR:
			logger.WithFields(metrics).Error(fmt.Sprintf("性能指标: %s", operation))
		}
	}
}

// 错误处理便捷函数

// LogError 记录错误
func LogError(ctx context.Context, err error, message string, fields ...map[string]interface{}) {
	logger := LoggerFromContext(ctx)

	var combinedFields map[string]interface{}
	if len(fields) > 0 {
		combinedFields = fields[0]
	}

	if combinedFields == nil {
		combinedFields = make(map[string]interface{})
	}
	combinedFields["error_type"] = fmt.Sprintf("%T", err)

	logger.WithFields(combinedFields).WithError(err).Error(message)
}

// LogPanicRecovery 记录panic恢复
func LogPanicRecovery(ctx context.Context, recovered interface{}, operation string) {
	logger := LoggerFromContext(ctx)

	fields := map[string]interface{}{
		"panic_value": recovered,
		"operation":   operation,
		"stack":       GetCallStack(2, 10),
	}

	logger.WithFields(fields).Error("程序panic已恢复")
}

// 配置便捷函数

// SetupDevelopment 设置开发环境日志
func SetupDevelopment(appName string) {
	logger, _ := NewLogger(
		WithLevel(DEBUG),
		WithFormat(TextFormat),
		WithColor(true),
		WithCaller(true),
		WithConsoleOutput(true),
		WithTrace(true, 5, 1.0),
		WithAppInfo(appName, "development"),
	)
	SetDefaultLogger(logger)
}

// SetupProduction 设置生产环境日志
func SetupProduction(appName, logDir string) error {
	if err := EnsureLogDir(logDir); err != nil {
		return fmt.Errorf("创建日志目录失败: %w", err)
	}

	logger, err := NewLogger(
		WithLevel(INFO),
		WithFormat(JSONFormat),
		WithColor(false),
		WithCaller(false),
		WithConsoleOutput(false),
		WithFileOutput(filepath.Join(logDir, appName+".log"),
			WithRotation(BothRotation),
			WithMaxSize(100),
			WithMaxAge(30),
			WithCompress(true),
		),
		WithTrace(true, 3, 0.1),
		WithAppInfo(appName, "production"),
		WithSanitize(true, DefaultSanitizeFields(), DefaultSanitizePatterns()),
	)

	if err != nil {
		return fmt.Errorf("创建生产日志器失败: %w", err)
	}

	// 添加错误文件钩子
	errorHook, err := ErrorFileHook(filepath.Join(logDir, appName+"_error.log"))
	if err == nil {
		logger.AddHook(errorHook)
	}

	SetDefaultLogger(logger)
	return nil
}

// SetupTest 设置测试环境日志
func SetupTest() {
	logger, _ := NewTestLogger()
	SetDefaultLogger(logger)
}

// 清理函数

// Cleanup 清理资源
func Cleanup() {
	Close()
}

// GracefulShutdown 优雅关闭
func GracefulShutdown(timeout time.Duration) error {
	done := make(chan error, 1)

	go func() {
		done <- Close()
	}()

	select {
	case err := <-done:
		return err
	case <-time.After(timeout):
		return fmt.Errorf("关闭超时")
	}
}
